home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Franz PD / Franz PD Disk #047 (1990)(Amiga User Group Deutschland e.V.)[v Disaster Master 2].zip / Franz PD Disk #047 (1990)(Amiga User Group Deutschland e.V.)[v Disaster Master 2].adf / Corral / corral.c < prev    next >
C/C++ Source or Header  |  1989-07-02  |  12KB  |  481 lines

  1. /*********************************************************
  2. *                                                        *
  3. *                 program:      corral                   *
  4. *          ==================================            *
  5. *                                                        *
  6. *       date: 19-JUN-1989     by: ANDREAS NEUPER         *
  7. *                                                        *
  8. *    compile: AZTEC_C3.4 +ff  link: -ls -lm -lc +Cb      *
  9. *                                                        *
  10. *                   release V1.205                       *
  11. *                                                        *
  12. *   suffix-files, headlines, arg-handling, auto-sizing   *
  13. *                                                        *
  14. *   file-request, centering, turning, 4gadget-handling   *
  15. *                                                        *
  16. **********************************************************
  17. *                                                        *
  18. *  BUGS:                                                 *
  19. *                                                        *
  20. *  LACK:                                                 *
  21. *                                                        *
  22. *********************************************************/
  23. #include <stdio.h>
  24. #include <math.h>
  25. #include <time.h>
  26. #include <graphics/gfxbase.h>
  27. #include <graphics/rastport.h>
  28. #include <graphics/display.h>
  29. #include <intuition/intuition.h>
  30.  
  31. #define  dPI            6.2831853072
  32. #define  MAX            2000
  33. #define  sqr(x)         ((x)*(x))
  34. #define  wp(x,y)        WritePixel(rp,(long)((x)<<1),(long)(y));WritePixel(rp,(long)(((x)<<1)+1),(long)(y))
  35.  
  36. int   Nummer,radius=30,offset=110;
  37. int   Menge_x[MAX],Menge_y[MAX];
  38. char  titles[90],buf[18];
  39.  
  40. struct IntuitionBase *IntuitionBase;
  41. struct GfxBase       *GfxBase;
  42. struct RastPort      *rp;
  43. struct Window        *window,*strwindow;
  44. struct IntuiMessage  *message;
  45. struct Message       *GetMsg();
  46. struct Gadget        *GadgetPtr;
  47. ULONG  MessageClass;
  48. USHORT code;
  49. extern double ran();
  50. extern double sqrt();
  51. unsigned char undostr[100],outstr[100];
  52.  
  53. struct StringInfo string =
  54. {  outstr,undostr,
  55.    0,100,0,0,
  56.    0,0,0,0,
  57.    NULL,0,NULL
  58. };
  59.  
  60. short sgp[] =
  61. {
  62.    0,0, 322,0, 322,12, 0,12, 0,0
  63. };
  64.  
  65. struct Border sgb =
  66. {
  67.    -2,-2,1,0,JAM1,5,sgp,NULL
  68. };
  69.  
  70. struct IntuiText sgt =
  71. {
  72.    3,0,JAM2,-42,1,NULL,(UBYTE *)"FILE",NULL
  73. };
  74.  
  75. struct Gadget StrGadg =
  76. {
  77.    NULL,
  78.    50,5,320,10,
  79.    GADGHCOMP,
  80.    RELVERIFY|STRINGCENTER,
  81.    STRGADGET,
  82.    (APTR)&sgb,
  83.    NULL,
  84.    &sgt,
  85.    NULL,
  86.    (APTR)&string,
  87.    5,NULL
  88. };
  89.  
  90. short gp[] =
  91. {
  92.    0,0, 11,0, 11,11, 0,11, 0,0
  93. };
  94.  
  95. struct Border gb =
  96. {
  97.    -1,-1,1,0,JAM1,5,gp,NULL
  98. };
  99. struct IntuiText gtr =
  100. {
  101.    2,0,JAM2,1,1,NULL,(UBYTE *)"R",NULL
  102. };
  103.  
  104. struct Gadget RotGadg =
  105. {
  106.    NULL,
  107.    -10,-10,
  108.    10, 10,
  109.    GADGHCOMP|GRELRIGHT|GRELBOTTOM,
  110.    RELVERIFY,
  111.    BOOLGADGET,
  112.    (APTR)&gb,
  113.    NULL,
  114.    >r,
  115.    NULL,NULL,
  116.    4,   NULL
  117. };
  118.  
  119. struct IntuiText gtv =
  120. {
  121.    2,0,JAM2,1,1,NULL,(UBYTE *)"V",NULL
  122. };
  123.  
  124. struct Gadget VerGadg =
  125. {
  126.    &RotGadg,
  127.    -10, 1,
  128.    10, 10,
  129.    GADGHCOMP|GRELRIGHT,
  130.    RELVERIFY,
  131.    BOOLGADGET,
  132.    (APTR)&gb,
  133.    NULL,
  134.    >v,
  135.    NULL,NULL,
  136.    3,   NULL
  137. };
  138.  
  139. struct IntuiText gth =
  140. {
  141.    2,0,JAM2,1,1,NULL,(UBYTE *)"H",NULL
  142. };
  143.  
  144. struct Gadget HorGadg =
  145. {
  146.    &VerGadg,
  147.    1,-10,
  148.    10,10,
  149.    GADGHCOMP|GRELBOTTOM,
  150.    RELVERIFY,
  151.    BOOLGADGET,
  152.    (APTR)&gb,
  153.    NULL,
  154.    >h,
  155.    NULL,NULL,
  156.    2,   NULL
  157. };
  158.  
  159. struct IntuiText gtc =
  160.    {
  161.    2,0,JAM2,1,1,NULL,(UBYTE *)"C",NULL
  162.    };
  163.  
  164. struct Gadget CenterGadg =
  165. {
  166.    &HorGadg,
  167.    1, 1,
  168.    10,10,
  169.    GADGHCOMP,
  170.    RELVERIFY,
  171.    BOOLGADGET,
  172.    (APTR)&gb,
  173.    NULL,
  174.    >c,
  175.    NULL,NULL,
  176.    1,   NULL
  177. };
  178.  
  179. struct NewWindow nw =
  180.   {
  181.    18, 8,    /* Ecken */
  182.    100,60,/*Breit,Hoch*/
  183.    3,  1,     /* Pens */
  184.    CLOSEWINDOW|REFRESHWINDOW|GADGETUP,
  185.    WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG|SUPER_BITMAP|GIMMEZEROZERO,
  186.    &CenterGadg,
  187.    NULL,     /* Gadget  Checkmark */
  188.    (UBYTE *)"Spektrum Februar 1989",
  189.    NULL,     /* Zeiger auf Screen */
  190.    NULL,/* Zeiger auf SuperBitMap */
  191.    40,  20,    /* Min. Breit,Hoch */
  192.    480,240,    /* Max. Breit,Hoch */
  193.    WBENCHSCREEN
  194.   };
  195.  
  196. struct NewWindow nw2 =
  197.   {
  198.    20, 100,
  199.    375,30,
  200.    2,  1,
  201.    CLOSEWINDOW|GADGETUP,
  202.    WINDOWCLOSE|BORDERLESS|GIMMEZEROZERO|ACTIVATE,
  203.    &StrGadg,
  204.    NULL,
  205.    (UBYTE *)"OUTPUT_filename:        (Spektrum Feb.1989)",
  206.    NULL,
  207.    NULL,
  208.    20, 10,
  209.    480,50,
  210.    WBENCHSCREEN
  211.   };
  212.  
  213. close_all()
  214. {  extern void CloseLibrary();
  215.    extern void CloseWindow();
  216.  
  217.    if (window)        CloseWindow(window);
  218.    if (GfxBase)       CloseLibrary(GfxBase);
  219.    if (IntuitionBase) CloseLibrary(IntuitionBase);
  220.    exit(FALSE);
  221. }
  222.  
  223. open_all()
  224. {  void                    *OpenLibrary();
  225.    extern struct  Window   *OpenWindow();
  226.  
  227.    if (!(GfxBase = (struct GfxBase *)
  228.       OpenLibrary("graphics.library", (long)0)))
  229.       close_all();
  230.  
  231.    if (!(IntuitionBase = (struct IntuitionBase *)
  232.       OpenLibrary("intuition.library", (long)0)))
  233.       close_all();
  234.  
  235.    if (!(window = (struct Window *)
  236.       OpenWindow(&nw)))
  237.       close_all();
  238.  
  239.    rp = window->RPort;
  240.    SetDrMd(rp,JAM1);    /* Drawmode  setzen                  */
  241.    SetAPen(rp,(long)3); /* Farbregister zum Zeichnen setzen  */
  242. }
  243.  
  244. center()
  245. {  register int i,sumx=0,sumy=0;
  246.    int   maxrad=0,rad,hoch1=0,hoch2=0,breit1=0,breit2=0;
  247.  
  248.    for(i=0;i<Nummer;i++)
  249.    {
  250.       sumx += Menge_x[i];
  251.       sumy += Menge_y[i];
  252.    }
  253.    sumx = -sumx/Nummer;
  254.    sumy = -sumy/Nummer;
  255.    for(i=0;i<Nummer;i++)
  256.    {
  257.       Menge_x[i] += sumx;
  258.       Menge_y[i] += sumy;
  259.       rad = sqr(Menge_x[i])+sqr(Menge_y[i]);
  260.       if ( rad > maxrad ) maxrad = rad;
  261.       if ( Menge_x[i] > breit2 ) breit2 = Menge_x[i];
  262.       if ( Menge_y[i] > hoch2 ) hoch2 = Menge_y[i];
  263.       if ( Menge_x[i] < breit1 ) breit1 = Menge_x[i];
  264.       if ( Menge_y[i] < hoch1 ) hoch1 = Menge_y[i];
  265.    }
  266.    sprintf(titles,"max.  Radius: %.2f   Width: %3d   Height: %3d   Shift(x|y): (%2d |%2d )",
  267.       sqrt((double)maxrad),(breit2-breit1),(hoch2-hoch1),sumx,sumy);
  268.    SetWindowTitles(window,buf,titles);
  269. }
  270.  
  271. rotate()
  272. {  register int i,help;
  273.  
  274.    for(i=0;i<Nummer;i++)
  275.    {  help = Menge_x[i];
  276.       Menge_x[i] = Menge_y[i];
  277.       Menge_y[i] = -help;
  278. }  }
  279.  
  280. void  shift(shiftn)
  281. int   shiftn;
  282. {  register int   i;
  283.  
  284.    SetAPen(rp,(long)0);
  285.    for(i=0;i<Nummer;i++) {wp(Menge_x[i]+offset,Menge_y[i]+offset);}
  286.    SetAPen(rp,(long)3);
  287.    if (shiftn>0)
  288.    {  offset += shiftn;
  289.       radius += shiftn;
  290.    } else switch(shiftn)
  291.    {
  292.       case -1 : center();break;
  293.       case -2 : for(i=0;i<Nummer;i++) Menge_x[i]=-Menge_x[i];break;
  294.       case -3 : for(i=0;i<Nummer;i++) Menge_y[i]=-Menge_y[i];break;
  295.       case -4 : rotate();break;
  296.    }
  297.    if(((offset<<1)+window->TopEdge<240)&&((offset<<2)+window->LeftEdge<475))
  298.       SizeWindow(window,(long)((offset<<2)-window->Width),(long)((offset<<1)-window->Height+10));
  299.    else {
  300.       MoveWindow(window,-1*(long)(window->LeftEdge),-1*(long)(window->TopEdge));
  301.       Delay(2L);
  302.       if(((offset<<1)+window->TopEdge<240)&&((offset<<2)+window->LeftEdge<475))
  303.          SizeWindow(window,(long)((offset<<2)-window->Width),(long)((offset<<1)-window->Height+10));
  304.    }
  305.    Delay(12L);
  306.    for(i=0;i<Nummer;i++) {wp(Menge_x[i]+offset,Menge_y[i]+offset);}
  307.    RefreshGadgets(&CenterGadg,window,NULL);
  308. }
  309.  
  310. void eingabe(argc,arg)
  311. int  argc;
  312. char **arg;
  313. {  FILE *infile;
  314.    char fn[40];
  315.    int k,position;
  316.    short x,y;
  317.  
  318.    x = window->Width+window->LeftEdge;
  319.    y = window->Height+window->TopEdge;
  320.    if ( ( argc > 2 ) || ( ( argc == 2 ) && ( arg[1][0] == '?' ) ) )
  321.       { fprintf(stderr,"\n  \033[7;30;43m\033[0;33;42m USAGE : \033[0;33m   corral [ workFILE ]\033[0;31m\n\n"); close_all(); exit(10); }
  322.    if ( argc == 1 )
  323.    {  Menge_x[0]=0;   Menge_y[0]=0;
  324.       Nummer = 1;
  325.       radius = 10;
  326.       offset = 25;
  327.  
  328.       if (!(strwindow = (struct Window *)  OpenWindow(&nw2)))
  329.       {
  330.          if (strwindow) CloseWindow(strwindow);
  331.          close_all();
  332.       }
  333.         ActivateGadget(&StrGadg,window,NULL);
  334.       for(;;)
  335.       if (message = (struct IntuiMessage *) GetMsg(strwindow->UserPort))
  336.       {
  337.          code = message->Code;
  338.          MessageClass = message->Class;
  339.          GadgetPtr = (struct Gadget *) message->IAddress;
  340.          ReplyMsg(message);
  341.          if ((MessageClass == GADGETUP)||(MessageClass == CLOSEWINDOW))
  342.          {  if (strwindow) CloseWindow(strwindow);
  343.             break;
  344.       }  }
  345.       infile = fopen(outstr,"r");
  346.    } else infile = fopen(arg[1],"r");
  347.    if ( infile == (long)0 )
  348.    {
  349.       Menge_x[0]=0;   Menge_y[0]=0;
  350.       Nummer = 1;
  351.       radius = 10;
  352.       offset = 25;
  353.    } else {
  354.       fscanf(infile,"%d",&Nummer);
  355.       for(k=0;k<Nummer;k++) fscanf(infile,"%d%d",&Menge_x[k],&Menge_y[k]);
  356.       fclose(infile);
  357.       radius = (int)(sqrt((double)Nummer)*2)+2;
  358.       offset = radius+5;
  359.       if (Nummer<75) offset=25;
  360.       if (offset < 120) shift(0);
  361.       else {fprintf(stderr,"Too many particles!\n");close_all();}
  362.    }
  363.    RefreshGadgets(&CenterGadg,window,NULL);
  364.  
  365. void ausgabe(argc,argv)
  366. int  argc;
  367. char **argv;
  368. {  FILE *outfile;
  369.    char fn[100],*help1;
  370.    unsigned char *help2;
  371.    register int j,k;
  372.  
  373.    if ( argc < 2 )
  374.    {
  375.       help1=fn;help2=outstr; /*warning ok!*/
  376.       while((*help1 = *help2++)&&(*help2 != '.'))help1++;
  377.       *(help1+1) = '\0';
  378.    } else {
  379.       k=strlen(argv[1]);
  380.       for(j=0;(j<k)&&(argv[1][j]!='.');j++) fn[j] = argv[1][j];
  381.       fn[j] = (char)0;
  382.    }
  383.    fn[(k=strlen(fn))]='.';
  384.    ftoa((double)Nummer,buf,0,1);
  385.    for(j=0;j<6;j++) fn[j+k+1] = buf[j];
  386.    outfile = fopen(fn,"w");
  387.  
  388.    if ( outfile == (long)0 ) { fprintf(stderr,"  \033[0;33mOutput-File cannot be opened by CORRAL !\033[0;31m\n\n"); close_all(); exit(5); }
  389.  
  390.    fprintf(outfile,"%d\n",Nummer);
  391.    for(k=0;k<Nummer;k++) fprintf(outfile,"%d %d\n",Menge_x[k],Menge_y[k]);
  392.    fclose(outfile);
  393. }
  394.  
  395. double random()    /* nur etwas langsamer, dafür zufälliger */
  396. {    long    timer,    *zeroo = 0;
  397.    timer = time(zeroo);
  398.    return((ran()*.9+(double)(timer%10)/(double)100));
  399. }
  400.  
  401. void  corral(argc,argv)
  402. int argc;
  403. char **argv;
  404. {  register int   i,x,y;
  405.    register short Kontakt;
  406.    int            x2,y2,Anzahl,Abstand;
  407.    double         Wahl,Winkel;
  408.  
  409.    for(i=0;i<Nummer;i++) {wp(Menge_x[i]+offset,Menge_y[i]+offset);}
  410.    Kontakt = 0;
  411.    sprintf(titles,"CORRAL      -     a Fractal Tree                 ©JAN");
  412.    while(radius<180)
  413.    {
  414.       Winkel = dPI*Wahl;
  415.       x = radius*cos(Winkel);
  416.       y = radius*sin(Winkel);
  417.  
  418.       x2 = y2 = Abstand = 0;/* für neues Teilchen NULL setzen */
  419.  
  420.       do {
  421.          x2 = x;
  422.          y2 = y;  /* x3 and y3  o n l y  necessary for s.a.w. */
  423.  
  424.          SetAPen(rp,(long)0);
  425.          wp(x+offset,y+offset);
  426.          do {
  427.             Wahl = random();                      /* random walk */
  428.             if ( Wahl < 0.25 ) --x;
  429.             else {
  430.                if ( Wahl < 0.5 ) x++;
  431.                else {
  432.                   if ( Wahl < 0.75 ) --y;
  433.                   else y++;
  434.             }  }
  435.          }while((x == x2) && (y == y2));/* self avoiding walk */
  436.          
  437.          SetAPen(rp,(long)1);
  438.          wp(x+offset,y+offset);
  439.          Abstand = sqr(x)+sqr(y);
  440.  
  441.          for(i=0;i<Nummer;i++)
  442.          {
  443.             if( ( (x-1) == Menge_x[i] ) && ( y == Menge_y[i] ) ) Kontakt = 1;
  444.             if( ( (x+1) == Menge_x[i] ) && ( y == Menge_y[i] ) ) Kontakt = 1;
  445.             if( ( x == Menge_x[i] ) && ( (y-1) == Menge_y[i] ) ) Kontakt = 1;
  446.             if( ( x == Menge_x[i] ) && ( (y+1) == Menge_y[i] ) ) Kontakt = 1;
  447.          }   
  448.       }while((Abstand < sqr(radius)) && (Kontakt == 0));
  449.       if ( Kontakt == 0 )
  450.       {  SetAPen(rp,(long)0);
  451.          wp(x+offset,y+offset);
  452.       } else {
  453.          Menge_x[Nummer] = x;
  454.          Menge_y[Nummer++] = y;
  455.          Kontakt = 0;
  456.          if (Abstand > (sqr(radius)-3)) shift(5);
  457.          sprintf(buf,"%d Particles",Nummer);
  458.          SetWindowTitles(window,buf,titles);
  459.          if (Nummer == (Nummer/100)*100) ausgabe(argc,argv);
  460.       }
  461.       if (message = (struct IntuiMessage *) GetMsg(window->UserPort))
  462.       {  code = message->Code;
  463.          MessageClass = message->Class;
  464.          GadgetPtr = (struct Gadget *) message->IAddress;
  465.          ReplyMsg(message);
  466.          if (MessageClass == GADGETUP) shift(-(GadgetPtr->GadgetID));
  467.          if (MessageClass == CLOSEWINDOW) return();
  468. }  }  }
  469.  
  470. main(argc,argv)
  471. int argc;
  472. char **argv;
  473. {
  474.    open_all();
  475.    eingabe(argc,argv);
  476.    corral(argc,argv);
  477.    ausgabe(argc,argv);
  478.    center();Delay(100L);
  479.    close_all();
  480. }